home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HAM Radio 3.2
/
Ham Radio Version 3.2 (Chestnut CD-ROMs)(1993).ISO
/
packet
/
n17jsrc
/
icmphdr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-27
|
2KB
|
103 lines
/* ICMP header conversion routines
* Copyright 1991 Phil Karn, KA9Q
*/
#include "global.h"
#include "mbuf.h"
#include "internet.h"
#include "ip.h"
#include "icmp.h"
/* Generate ICMP header in network byte order, link data, compute checksum */
struct mbuf *
htonicmp(icmp,data)
struct icmp *icmp;
struct mbuf *data;
{
struct mbuf *bp;
register char *cp;
int16 checksum;
if((bp = pushdown(data,ICMPLEN)) == NULLBUF)
return NULLBUF;
cp = bp->data;
*cp++ = icmp->type;
*cp++ = icmp->code;
cp = put16(cp,0); /* Clear checksum */
switch(icmp->type){
case ICMP_DEST_UNREACH:
if(icmp->code == ICMP_FRAG_NEEDED){
/* Deering/Mogul max MTU indication */
cp = put16(cp,0);
cp = put16(cp,icmp->args.mtu);
} else
cp = put32(cp,0L);
break;
case ICMP_PARAM_PROB:
*cp++ = icmp->args.pointer;
*cp++ = 0;
cp = put16(cp,0);
break;
case ICMP_REDIRECT:
cp = put32(cp,icmp->args.address);
break;
case ICMP_ECHO:
case ICMP_ECHO_REPLY:
case ICMP_TIMESTAMP:
case ICMP_TIME_REPLY:
case ICMP_INFO_RQST:
case ICMP_INFO_REPLY:
cp = put16(cp,icmp->args.echo.id);
cp = put16(cp,icmp->args.echo.seq);
break;
default:
cp = put32(cp,0L);
break;
}
/* Compute checksum, and stash result */
checksum = cksum(NULLHEADER,bp,len_p(bp));
cp = &bp->data[2];
cp = put16(cp,checksum);
return bp;
}
/* Pull off ICMP header */
int
ntohicmp(icmp,bpp)
struct icmp *icmp;
struct mbuf **bpp;
{
char icmpbuf[8];
if(icmp == (struct icmp *)NULL)
return -1;
if(pullup(bpp,icmpbuf,8) != 8)
return -1;
icmp->type = icmpbuf[0];
icmp->code = icmpbuf[1];
switch(icmp->type){
case ICMP_DEST_UNREACH:
/* Retrieve Deering/Mogul MTU value */
if(icmp->code == ICMP_FRAG_NEEDED)
icmp->args.mtu = get16(&icmpbuf[6]);
break;
case ICMP_PARAM_PROB:
icmp->args.pointer = icmpbuf[4];
break;
case ICMP_REDIRECT:
icmp->args.address = get32(&icmpbuf[4]);
break;
case ICMP_ECHO:
case ICMP_ECHO_REPLY:
case ICMP_TIMESTAMP:
case ICMP_TIME_REPLY:
case ICMP_INFO_RQST:
case ICMP_INFO_REPLY:
icmp->args.echo.id = get16(&icmpbuf[4]);
icmp->args.echo.seq = get16(&icmpbuf[6]);
break;
}
return 0;
}